#include "cpu-scheduling.h"

/*最短作业优先算法, 优先执行服务时间较短的*/
void sjf(PCB *tasks) {
    Queue readyQueue, runningQueue, waitingQueue;
    initQueue(&readyQueue);
    initQueue(&runningQueue);
    initQueue(&waitingQueue);

    PCB *current = NULL;
    int currentTime = 0;
    PCB* last_task = tasks;

    while (1) {
        // 将到达的进程加入就绪队列
        PCB* tmp_task = last_task;
        while (tmp_task) {
            if(tmp_task->releaseTime <= currentTime){
                enqueue_releasetime_first(&readyQueue, tmp_task);
                last_task = tmp_task->next;
            }
            tmp_task = tmp_task->next;
        }

        // 如果就绪队列为空且没有运行的进程，时间前进
        if (isEmpty(&readyQueue) && !current) {
            currentTime++;
            continue;
        }

        // 选择就绪队列中首个任务作为当前执行的任务
        if (!current) {
            current = dequeue(&readyQueue);
        }
        // 选择就绪队列中剩余运行时间最短的进程
        PCB *shortest = NULL;
        if (current) {
            shortest = current;
        }
        for (PCB *p = readyQueue.head; p; p = p->next) {
            if (!shortest || (p->cpuTime - p->executedTime < shortest->cpuTime - shortest->executedTime)) {
                shortest = p;
            }
        }

        // 如果有更短的进程，且当前进程并没有开始执行
        if (shortest != current && 0 == current->executedTime) {
            if (current) {
                enqueue_lefttime_first(&readyQueue, current);
            }
            current = shortest;
            dequeue(&readyQueue);
        }

        // 执行当前进程
        if (current) {
            current->executedTime++;
            if (current->executedTime == current->cpuTime) {
                printf("P%d:%d\n", current->procID, currentTime + 1);
                free(current);
                current = NULL;
            }
        }

        // 检查是否所有进程都已完成
        if (isEmpty(&readyQueue) && !current && !last_task) {
            break;
        }

        currentTime++;
    }
}